﻿using System;
using System.Collections.Generic;
using Engine;
using Game;
namespace Mekiasm
{
    public class MekPlantsManager
    {
        public List<TerrainBrush> m_treeBrushesByType = new List<TerrainBrush>();

        public MekPlantsManager(int woodIndex, int leavesIndex)
        {
            Game.Random random = new Game.Random(55);
            int[] array = new int[]
            {
                    5,
                    6,
                    7,
                    8
            };
            for (int i = 0; i < array.Length; i++)
            {

                int height4 = array[i];
                int branchesCount = 1;
                TerrainBrush item = CreateTreeBrush(random, woodIndex, leavesIndex, height4, branchesCount, delegate (int y)
                {
                    float num7 = 0.4f;
                    if ((float)y < 0.2f * (float)height4)
                    {
                        num7 = 0f;
                    }
                    else if ((float)y >= 0.2f * (float)height4 && y <= height4)
                    {
                        num7 *= 1.5f;
                    }

                    return num7;
                }, delegate (int y)
                {
                    if ((float)y < (float)height4 * 0.3f || (float)y > (float)height4 * 0.9f)
                    {
                        return 0f;
                    }

                    float num6 = ((float)y < (float)height4 * 0.7f) ? (0.5f * (float)height4) : (0.35f * (float)height4);
                    return random.Float(0.33f, 1f) * num6;
                });
                m_treeBrushesByType.Add(item);
            }

        }

        public void Paint(SubsystemTerrain terrain, int x, int y, int z)
        {
            for (int i = 0; i < m_treeBrushesByType.Count; i++)
            {
                m_treeBrushesByType[i].Paint(terrain, x, y, z);
            }
        }

        public TerrainBrush CreateTreeBrush(Game.Random random, int woodIndex, int leavesIndex, int height, int branchesCount, Func<int, float> leavesProbabilityByHeight, Func<int, float> branchesLengthByHeight)
        {
            TerrainBrush terrainBrush = new TerrainBrush();
            terrainBrush.AddRay(0, -1, 0, 0, height, 0, 1, 1, 1, woodIndex);
            for (int i = 0; i < branchesCount; i++)
            {
                int x = 0;
                int num = random.Int(0, height);
                int z = 0;
                float s = branchesLengthByHeight(num);
                Vector3 vector = Vector3.Normalize(new Vector3(random.Float(-1f, 1f), random.Float(0f, 0.33f), random.Float(-1f, 1f))) * s;
                int x2 = (int)MathUtils.Round(vector.X);
                int y = num + (int)MathUtils.Round(vector.Y);
                int z2 = (int)MathUtils.Round(vector.Z);
                int cutFace = 0;
                if (MathUtils.Abs(vector.X) == MathUtils.Max(MathUtils.Abs(vector.X), MathUtils.Abs(vector.Y), MathUtils.Abs(vector.Z)))
                {
                    cutFace = 1;
                }
                else if (MathUtils.Abs(vector.Y) == MathUtils.Max(MathUtils.Abs(vector.X), MathUtils.Abs(vector.Y), MathUtils.Abs(vector.Z)))
                {
                    cutFace = 4;
                }

                terrainBrush.AddRay(x, num, z, x2, y, z2, 1, 1, 1, (Func<int?, int?>)((int? v) => v.HasValue ? null : new int?(ILibrary.setExtraData(woodIndex, cutFace))));
            }

            for (int j = 0; j < 3; j++)
            {
                terrainBrush.CalculateBounds(out Point3 min, out Point3 max);
                for (int k = min.X - 1; k <= max.X + 1; k++)
                {
                    for (int l = min.Z - 1; l <= max.Z + 1; l++)
                    {
                        for (int m = 1; m <= max.Y + 1; m++)
                        {
                            float num2 = leavesProbabilityByHeight(m);
                            if (random.Float(0f, 1f) < num2 && !terrainBrush.GetValue(k, m, l).HasValue && (terrainBrush.CountNonDiagonalNeighbors(k, m, l, leavesIndex) != 0 || terrainBrush.CountNonDiagonalNeighbors(k, m, l, (Func<int?, int>)((int? v) => (v.HasValue && ILibrary.GetBasicValue(v.Value) == ILibrary.GetBasicValue(woodIndex)) ? 1 : 0)) != 0))
                            {
                                terrainBrush.AddCell(k, m, l, 0);
                            }
                        }
                    }
                }

                terrainBrush.Replace(0, leavesIndex);
            }

            terrainBrush.AddCell(0, height, 0, leavesIndex);
            terrainBrush.Compile();
            return terrainBrush;
        }

    }
}
